////////////////////////////////////////////////////////////////////////////////
/// main.c
/// controls LCD hooked up to PD0 - PD5
/// Hardware: STK500
////////////////////////////////////////////////////////////////////////////////

//Include the Header file for Input/Output Operations
#include <avr/io.h>

#define F_CPU 8000000
#include <util/delay.h>

#define ENABLE 1


//function declarations
void pulseEnable();
void initialize();
void writeOneNibble(uint8_t command);
void writeAsNibbles(uint8_t command);
void writeLetter(uint8_t letter);
void setAddress(uint8_t address);


void helloFacebook();
void helloTumblr();
void psalm113();


//Begin the program
int main(void) { 
  ///////////////
  // Variables //
  ///////////////
  uint8_t i;
  
  DDRB = 255; //Set PORTB for Output 
  PORTB = 0; //Set all outputs low

  DDRD = 255; //set portD to all output

  //Delay to allow LCD to start up
  _delay_ms(500);
	
  //Start Up LCD
  initialize();

  //Set 4 bit mode
  writeOneNibble(0b00000010);
  /*
  PORTD = 0b00001000; //Set 4 bit mode
  pulseEnable();
  */
  
  //Set two line 5x7 mode
  writeAsNibbles(0b00101000);
  /*
  PORTD = 0b00001000; //2 line 5x7
  pulseEnable();
  PORTD = 0b00100000;
  pulseEnable();
  _delay_ms(100);
  */

  //Display On, underline On, blinking On
  writeAsNibbles(0b00001100);
  /*
  PORTD = 0b00000000; //display on underline on blink on
  pulseEnable();
  PORTD = 0b00111100;
  pulseEnable();
  */

  //Clear display and return home
  writeAsNibbles(0b00000001);
  _delay_ms(5);
  
  helloTumblr();

  setAddress(0x41);

  john330();
  
	
  for(;;)
    {;}
		
}

void pulseEnable(){
  //Off
  PORTD &= ~(1 << ENABLE);
  _delay_us(1);
  //On
  PORTD |= (1 << ENABLE);
  _delay_us(1);
  //Off
  PORTD &= ~(1 << ENABLE);
  _delay_us(100);
}

void initialize() {
  PORTD = 0b00001100; //init
  pulseEnable();
  _delay_us(4500);
	
  PORTD = 0b00001100; //init
  pulseEnable();
  _delay_us(4500);
	
  PORTD = 0b00001100; //init
  pulseEnable();
  _delay_us(150);
}

void writeOneNibble(uint8_t command) {
  //Write to PORTD
  PORTD = (command << 2);
  pulseEnable();
}

void writeAsNibbles(uint8_t command) {
  //write first nibble
  PORTD = ((command >> 4) << 2);
  pulseEnable();
  
  //write second nibble
  PORTD = ((command << 4) >> 2);
  pulseEnable();
}

void writeLetter(uint8_t letter) {
  //write first nibble
  PORTD = ((letter >> 4) << 2);
  PORTD |= 1; //set RS high
  pulseEnable();
  
  //write second nibble
  PORTD = ((letter << 4) >> 2);
  PORTD |= 1; //set RS high
  pulseEnable();
}

void setAddress(uint8_t address) {
  address |= (1 << 7);
  writeAsNibbles(address);
}


void helloFacebook() {
  writeLetter(0x48); //H
  writeLetter(0x65); //e
  writeLetter(0x6C); //l
  writeLetter(0x6C); //l
  writeLetter(0x6F); //o
  writeLetter(0x20); // 
  writeLetter(0x46); //F
  writeLetter(0x61); //a
  writeLetter(0x63); //c
  writeLetter(0x65); //e
  writeLetter(0x62); //b
  writeLetter(0x6F); //o
  writeLetter(0x6F); //o
  writeLetter(0x6B); //k
}

void helloTumblr() {
  writeLetter(0x48); //H
  writeLetter(0x65); //e
  writeLetter(0x6C); //l
  writeLetter(0x6C); //l
  writeLetter(0x6F); //o
  writeLetter(0x20); // 
  writeLetter(0x54); //T
  writeLetter(0x75); //u
  writeLetter(0x6D); //m
  writeLetter(0x62); //b
  writeLetter(0x6C); //l
  writeLetter(0x72); //r
}

void psalm113() {
  writeLetter(0x50); //P
  writeLetter(0x73); //s
  writeLetter(0x61); //a
  writeLetter(0x6C); //l
  writeLetter(0x6D); //m
  writeLetter(0x20); //
  writeLetter(0x31); //1
  writeLetter(0x3A); //:
  writeLetter(0x31); //1
  writeLetter(0x2D); //-
  writeLetter(0x33); //3



}
